package com.gsi.webstore.platform.storefront.internal.basket;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;

import com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension;
import com.gsi.webstore.platform.storefront.capi.order.GSILineItemCtnrCalculationResultView;
import com.gsi.webstore.platform.storefront.capi.order.GSITaxInformationBO;
import com.intershop.beehive.bts.capi.orderprocess.ProductLineItem;
import com.intershop.beehive.bts.capi.orderprocess.calculation.ComputedProductLineItem;
import com.intershop.beehive.core.capi.businessobject.BusinessObject;
import com.intershop.beehive.core.capi.businessobject.BusinessObjectContext;
import com.intershop.beehive.core.capi.common.SystemException;
import com.intershop.beehive.core.capi.log.Logger;
import com.intershop.beehive.core.capi.naming.NamingMgr;
import com.intershop.beehive.core.capi.preference.PreferenceMgr;
import com.intershop.beehive.core.capi.preference.PreferenceNotFoundException;
import com.intershop.beehive.core.capi.preference.ValueTypeViolationException;
import com.intershop.beehive.core.capi.url.Action;
import com.intershop.beehive.core.capi.url.Parameters;
import com.intershop.beehive.core.capi.url.URLComposition;
import com.intershop.beehive.xcs.capi.product.Product;
import com.intershop.component.product.capi.ProductBO;
import com.intershop.component.productconfiguration.capi.configuration.AbstractProductConfigurationBO;
import com.intershop.component.productconfiguration.capi.set.ProductConfigurationDecimalOptionBO;
import com.intershop.component.productconfiguration.capi.set.ProductConfigurationDecimalValueBO;
import com.intershop.component.productconfiguration.capi.set.ProductConfigurationIntOptionBO;
import com.intershop.component.productconfiguration.capi.set.ProductConfigurationIntValueBO;
import com.intershop.component.productconfiguration.capi.set.ProductConfigurationOptionBO;
import com.intershop.component.productconfiguration.capi.set.ProductConfigurationSectionBO;
import com.intershop.component.productconfiguration.capi.set.ProductConfigurationStringOptionBO;
import com.intershop.component.productconfiguration.capi.set.ProductConfigurationStringValueBO;
import com.intershop.component.productconfiguration.capi.set.ProductConfigurationValueBO;
import com.intershop.sellside.appbase.b2c.capi.calculation.LineItemCtnrCalculationResultView;
import com.intershop.sellside.appbase.b2c.capi.order.ProductConfigurationLineItemBO;
import com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO;

/**
 * This is the default implementation of the product customization extension of the line item BO.
 * It is used for providing product customization data to the order service.
 *
 * Whenever required this implementation can be replaced by projects. The new implementation needs to be registered in an implementations.component file like this one is in gsi_pf_sf:
 *  <implementation name="ProductConfigurationLineItemBOGSIExtFactory" implements="BusinessObjectExtensionFactory"
 *                   class="your implementation here">
 */
public class ORMProductConfigurationLineItemBOGSIExtensionImpl implements ProductConfigurationLineItemBOGSIExtension
{
    /**
     * The name of the custom attribute of object ProductConfigurationValue (List Element) which contains the product customization DisplayValue used for the order service XML element "DisplayValue".
     */
    public static final String LIST_ELEMENT_CUSTOM_ATTRIBUTE_NAME_DISPLAY_VALUE = "DisplayValue";

    /**
     * The name of the preference which contains the default value for the ItemId.
     */
    public static final String PREFERENCE_ORDER_XML_DEFAULT_ITEMID = "OrderXMLDefaultItemId";

    protected ProductConfigurationLineItemBO delegate;
    protected LineItemCtnrCalculationResultView _calculationResultView;
    protected Collection<GSITaxInformationBO> _itemPriceBasedTaxes;
    
    public ORMProductConfigurationLineItemBOGSIExtensionImpl(ProductConfigurationLineItemBO bo)
    {
        delegate = bo;
        BusinessObjectContext context = delegate.getContext();
        if (context != null) {
            _calculationResultView = context.getVariable("CalculationResultView");
            if (_calculationResultView == null) {
                Logger.error(this, "ORMProductConfigurationLineItemBOGSIExtensionImpl: cannot get CalculationResultView from {}", context.getClass().getName());
            }
        }
        else {
            Logger.error(this, "ORMProductConfigurationLineItemBOGSIExtensionImpl: no context available, cannot get CalculationResultView from context");
            _calculationResultView = null;
        }
    }
    
    /* (non-Javadoc)
     * @see com.intershop.beehive.core.capi.businessobject.BusinessObjectExtension#businessObjectCreated()
     */
    @Override
    public void businessObjectCreated()
    {
    }

    /* (non-Javadoc)
     * @see com.intershop.beehive.core.capi.businessobject.BusinessObjectExtension#businessObjectDeleted()
     */
    @Override
    public void businessObjectDeleted()
    {
    }

    /* (non-Javadoc)
     * @see com.intershop.beehive.core.capi.businessobject.BusinessObjectExtension#getBusinessObject()
     */
    @Override
    public BusinessObject getBusinessObject()
    {
        return delegate;
    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/Customizations/Customization/CustomizationId. This XML element is OPTIONAL.
     * There is a fall back strategy for the data used:
     * <ol>
     * <li> use Message Type of Location (= Section:MessageType (custom attribute)), if not available then:
     * <li> use Name         of Location (= Section:ID)
     * </ol>
     * 
     * @return data for OrderItem/Customization/Customizations/Customization/CustomizationId
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceCustomizationId()
     */
    @Override
    public String getOrderServiceCustomizationId()
    {
        String customizationId = null;
        ProductConfigurationOptionBO optionBO = delegate.getProductConfigurationOptionSelection().getOption();
        if (optionBO != null)
        {
            ProductConfigurationSectionBO sectionBO = optionBO.getSection();
    
            // use Location:MessageType first
            customizationId = sectionBO.getCustomAttributes().getString("MessageType");
            if (customizationId != null && customizationId.isEmpty()) {
                customizationId = null;
            }
            
            if (customizationId == null)
            {
                // fall back to Location:ID if there is no Location:MessageType
                customizationId = sectionBO.getID();
            }
        }
        
        return customizationId;
    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/Customizations/Customization/Instructions/Instructions/Key. This XML element is REQUIRED.
     * There is a fall back strategy for the data used:
     * <ol>
     * <li> use Message Type of Element (= Option:MessageType (custom attribute)), if not available then:
     * <li> use Name         of Element (= Option:ID)
     * </ol>
     * 
     * @return data for OrderItem/Customization/Customizations/Customization/Instructions/Instructions/Key
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceInstructionKey()
     */
    @Override
    public String getOrderServiceInstructionKey()
    {
        String instructionKey = null;
        ProductConfigurationOptionBO optionBO = delegate.getProductConfigurationOptionSelection().getOption();
        if (optionBO != null)
        {
            instructionKey = optionBO.getCustomAttributes().getString("MessageType");
            if (instructionKey != null && instructionKey.isEmpty()) {
                instructionKey = null;
            }
//            if (instructionKey == null)
//            {
//                instructionKey = optionBO.getSection().getCustomAttributes().getString("MessageType");
//                if (instructionKey != null && instructionKey.isEmpty()) {
//                    instructionKey = null;
//                }
//            }
            
            if (instructionKey == null)
            {
                instructionKey = optionBO.getID();
            }
        }
        
        return instructionKey;
    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/Customizations/Customization/Instructions/Instructions/Value. This XML element is REQUIRED.
     * 
     * The value the user typed in is returned here.
     * In case it is an Element with ListElements then the Value of the ListElement is used.
     * 
     * There are different types of values: string, int, decimal and product. For type product the SKU of the product is returned. All other types are simply converted to string.
     * 
     * @return data for OrderItem/Customization/Customizations/Customization/Instructions/Instructions/Value
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceInstructionValue()
     */
    @Override
    public String getOrderServiceInstructionValue()
    {
        Object objectValue = delegate.getProductConfigurationOptionSelection().getValue();
        if (objectValue instanceof ProductBO) {
            return ((ProductBO)objectValue).getSKU();
        }
        else {
            return objectValue.toString();
        }
    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/Customizations/Customization/Instructions/Instruction/DisplayTitle. This XML element is OPTIONAL.
     * 
     * The localized Display Name of the Element (= Option) is returned here.
     * 
     * @return data for OrderItem/Customization/Customizations/Customization/Instructions/Instruction/DisplayTitle
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceInstructionDisplayTitle()
     */
    @Override
    public String getOrderServiceInstructionDisplayTitle()
    {
        String displayTitle = null;
        
        ProductConfigurationOptionBO optionBO = delegate.getProductConfigurationOptionSelection().getOption();
        if (optionBO != null)
        {
            displayTitle = optionBO.getDisplayName();
        }
        
        return displayTitle;
    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/Customizations/Customization/Instructions/Instruction/DisplayValue. This XML element is OPTIONAL.
     * 
     * The DisplayValue is read from a custom attribute "DisplayValue" of the List Element.
     * If the Element does not contain List Elements (or if none of the List Elements was selected by consumer) then null is returned. Also, if there is a List Element but it does not has a custom attribute "DisplayValue" then null is returned.
     * 
     * @return data for OrderItem/Customization/Customizations/Customization/Instructions/Instruction/DisplayValue 
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceInstructionDisplayValue()
     */
    @Override
    public String getOrderServiceInstructionDisplayValue()
    {
        String displayValue = null;

        ProductConfigurationValueBO productConfigurationValue = delegate.getProductConfigurationOptionSelection().getConfigurationValue();
        if (productConfigurationValue != null)
        {
            displayValue = productConfigurationValue.getCustomAttributes().getString(LIST_ELEMENT_CUSTOM_ATTRIBUTE_NAME_DISPLAY_VALUE);
        }
        
        return displayValue;
    }

    /**
     * Returns if data is available to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/Customizations/Customization/ExtendedPrice. This XML element is OPTIONAL.
     * Checks if a price is assigned to the customization element/option.
     * 
     * @param baseProductLineItemBO  the parent PLI, the PLI of the base product
     * 
     * @return true if data for OrderItem/Customization/Customizations/Customization/ExtendedPrice is available, false if this XML element should be omitted
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#hasOrderServiceInstructionExtendedPrice(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
     */
    @Override
    public boolean hasOrderServiceInstructionExtendedPrice(ProductLineItemBO baseProductLineItemBO)
    {
        return delegate.getPrice() != null && delegate.getPrice().isAvailable();
    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/Customizations/Customization/ExtendedPrice/Amount. This XML element is OPTIONAL.
     * The price assigned to the customization element/option, if any.
     * 
     * @param baseProductLineItemBO  the parent PLI, the PLI of the base product
     * 
     * @return data for OrderItem/Customization/Customizations/Customization/ExtendedPrice/Amount
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceInstructionExtendedPriceAmount(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
     */
    @Override
    public BigDecimal getOrderServiceInstructionExtendedPriceAmount(ProductLineItemBO baseProductLineItemBO)
    {
        return delegate.getPrice() != null && delegate.getPrice().isAvailable() ? delegate.getPrice().getValue() : null;
    }

//    /**
//     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/Customizations/Customization/ExtendedPrice/PromotionalDiscounts. This XML element is OPTIONAL.
//     * Each element in the returned collection is used to create one OrderItem/Customization/Customizations/Customization/ExtendedPrice/PromotionalDiscounts/Discount XML element.
//     * The promotional discounts for the customization element/option, if any.
//     * 
//     * @param baseProductLineItemBO  the parent PLI, the PLI of the base product
//     * 
//     * @return data for OrderItem/Customization/Customizations/Customization/ExtendedPrice/PromotionalDiscounts, may return null or an empty collection
//     * 
//     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceInstructionExtendedPricePromotionalDiscounts(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
//     */
//    @Override
//    public Collection<Discount> getOrderServiceInstructionExtendedPricePromotionalDiscounts(ProductLineItemBO baseProductLineItemBO)
//    {
//        // TODO Auto-generated method stub
//        if (!delegate.getAppliedItemDiscounts().isEmpty())
//        {
//            List<Discount> discounts = new ArrayList<Discount>();
//            
//            for (final Discount discount : delegate.getAppliedItemDiscounts())
//            {
//                discounts.add(getMerchandiseDiscount("OrderCreateRequest/Order/OrderItems/OrderItem/Customization/Customizations/Customization/ExtendedPrice", baseProductLineItemBO, discount, context));
//            }
//        }
//        return null;
//    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/Customizations/Customization/ExtendedPrice/TaxData/TaxClass. This XML element is OPTIONAL.
     * The tax class for the customization element/option, if any.
     * The tax class is taken from a product. There is a fall back strategy for determining the product used:
     * <ol>
     * <li> use the product set at as offered product at the PLI (the dependent PLI for the option's/element's value), if not available then:
     * <li> if a customization SKU is assigned to an Element/ListElement then this customization SKU is used. If not then:
     * <li> use offered product of baseProductLineItemBO
     * </ol>
     * 
     * @param baseProductLineItemBO  the parent PLI, the PLI of the base product
     * 
     * @return data for OrderItem/Customization/Customizations/Customization/ExtendedPrice/TaxData/TaxClass
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceInstructionExtendedPriceTaxDataTaxClass(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
     */
    @Override
    public String getOrderServiceInstructionExtendedPriceTaxDataTaxClass(ProductLineItemBO baseProductLineItemBO)
    {
        Product optionProduct = delegate.getProduct();
        if (optionProduct != null) {
            return optionProduct.getTaxClassID();
        }

        // check value
        ProductConfigurationValueBO productConfigurationValue = delegate.getProductConfigurationOptionSelection().getConfigurationValue();
        if (productConfigurationValue != null)
        {
            Product serviceProduct = null;

            if (productConfigurationValue instanceof ProductConfigurationIntValueBO) {
                serviceProduct = ((ProductConfigurationIntValueBO)productConfigurationValue).getServiceProduct();
            }
            else if (productConfigurationValue instanceof ProductConfigurationDecimalValueBO) {
                serviceProduct = ((ProductConfigurationDecimalValueBO)productConfigurationValue).getServiceProduct();
            }
            else if (productConfigurationValue instanceof ProductConfigurationStringValueBO) {
                serviceProduct = ((ProductConfigurationStringValueBO)productConfigurationValue).getServiceProduct();
            }

            if (serviceProduct != null) {
                return serviceProduct.getSKU();
            }
        }

        // check option
        ProductConfigurationOptionBO optionBO = delegate.getProductConfigurationOptionSelection().getOption();
        if (optionBO != null)
        {
            Product serviceProduct = null;

            if (optionBO instanceof ProductConfigurationIntOptionBO) {
                serviceProduct = ((ProductConfigurationIntOptionBO)optionBO).getServiceProduct();
            }
            else if (optionBO instanceof ProductConfigurationDecimalOptionBO) {
                serviceProduct = ((ProductConfigurationDecimalOptionBO)optionBO).getServiceProduct();
            }
            else if (optionBO instanceof ProductConfigurationStringOptionBO) {
                serviceProduct = ((ProductConfigurationStringOptionBO)optionBO).getServiceProduct();
            }

            if (serviceProduct != null) {
                return serviceProduct.getSKU();
            }
        }

        return baseProductLineItemBO.getProduct().getTaxClassID();
    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/Customizations/Customization/ExtendedPrice/TaxData/Taxes. This XML element is OPTIONAL.
     * Each element in the returned collection is used to create one OrderItem/Customization/Customizations/Customization/ExtendedPrice/TaxData/Taxes/Tax XML element.
     * The taxes for the customization element/option, if any.
     * 
     * @param baseProductLineItemBO  the parent PLI, the PLI of the base product
     * 
     * @return data for OrderItem/Customization/Customizations/Customization/ExtendedPrice/TaxData/Taxes, may return null or an empty collection
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceInstructionExtendedPriceTaxDataTaxes(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
     */
    @Override
    public Collection<GSITaxInformationBO> getOrderServiceInstructionExtendedPriceTaxDataTaxes(ProductLineItemBO baseProductLineItemBO)
    {
        if (_itemPriceBasedTaxes != null)
        {
            return _itemPriceBasedTaxes;
        }

        if (_calculationResultView != null) {  // if _calculationResultView is null an error log will have been written by constructor
            final ComputedProductLineItem cpli = _calculationResultView.getPLI(delegate.getID());
            if (cpli != null)
            {
                return _itemPriceBasedTaxes = ((GSILineItemCtnrCalculationResultView)_calculationResultView).getItemPriceBasedTaxes(cpli.getID());
            }
            else
            {
                Logger.error(this, "ORMProductConfigurationLineItemBOGSIExtensionImpl.getOrderServiceInstructionExtendedPriceTaxDataTaxes: cannot get ItemPriceBasedTaxes for ComputedProductLineItem with id {}", cpli.getID());
            }
        }
        return new ArrayList<GSITaxInformationBO>(0);
    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/Customizations/Customization/ExtendedPrice/UnitPrice. This XML element is OPTIONAL.
     * The unit price assigned to the customization element/option, if any.
     * 
     * @param baseProductLineItemBO  the parent PLI, the PLI of the base product
     * 
     * @return data for OrderItem/Customization/Customizations/Customization/ExtendedPrice/UnitPrice
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceInstructionExtendedPriceUnitPrice(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
     */
    @Override
    public BigDecimal getOrderServiceInstructionExtendedPriceUnitPrice(ProductLineItemBO baseProductLineItemBO)
    {
        // TODO there is currently no unit price available
        //return delegate.getPrice() != null && delegate.getPrice().isAvailable() ? delegate.getPrice().getValue() : null;
        return null;
    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/Customizations/Customization/ItemId. This XML element is OPTIONAL.
     * There is a fall back strategy for the data used:
     * <ol>
     * <li> If a customization SKU is assigned to an Element/ListElement then this customization SKU is used. If not then:
     * <li> If a preference is set at the current channel then it is used. If not then:
     * <li> null is returned.
     * </ol>
     * 
     * @return data for OrderItem/Customization/Customizations/Customization/ItemId
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceCustomizationItemId()
     */
    @Override
    public String getOrderServiceCustomizationItemId()
    {
        // check value
        ProductConfigurationValueBO productConfigurationValue = delegate.getProductConfigurationOptionSelection().getConfigurationValue();
        if (productConfigurationValue != null)
        {
            if (productConfigurationValue instanceof ProductConfigurationIntValueBO) {
                Product serviceProduct = ((ProductConfigurationIntValueBO)productConfigurationValue).getServiceProduct();
                if (serviceProduct != null) {
                    return serviceProduct.getSKU();
                }
            }
            else if (productConfigurationValue instanceof ProductConfigurationDecimalValueBO) {
                Product serviceProduct = ((ProductConfigurationDecimalValueBO)productConfigurationValue).getServiceProduct();
                if (serviceProduct != null) {
                    return serviceProduct.getSKU();
                }
            }
            else if (productConfigurationValue instanceof ProductConfigurationStringValueBO) {
                Product serviceProduct = ((ProductConfigurationStringValueBO)productConfigurationValue).getServiceProduct();
                if (serviceProduct != null) {
                    return serviceProduct.getSKU();
                }
            }
        }

        // check option
        ProductConfigurationOptionBO optionBO = delegate.getProductConfigurationOptionSelection().getOption();
        if (optionBO != null)
        {
            if (optionBO instanceof ProductConfigurationIntOptionBO) {
                Product serviceProduct = ((ProductConfigurationIntOptionBO)optionBO).getServiceProduct();
                if (serviceProduct != null) {
                    return serviceProduct.getSKU();
                }
            }
            else if (optionBO instanceof ProductConfigurationDecimalOptionBO) {
                Product serviceProduct = ((ProductConfigurationDecimalOptionBO)optionBO).getServiceProduct();
                if (serviceProduct != null) {
                    return serviceProduct.getSKU();
                }
            }
            else if (optionBO instanceof ProductConfigurationStringOptionBO) {
                Product serviceProduct = ((ProductConfigurationStringOptionBO)optionBO).getServiceProduct();
                if (serviceProduct != null) {
                    return serviceProduct.getSKU();
                }
            }
        }
        
        // check channel preference
        PreferenceMgr pmgr = (PreferenceMgr)NamingMgr.getInstance().lookupManager(PreferenceMgr.REGISTRY_NAME);
        try
        {
            String itemId = pmgr.getStringPreference(PREFERENCE_ORDER_XML_DEFAULT_ITEMID, ((ProductLineItem)delegate.getCustomAttributes()).getDomain());
            if (itemId != null) {
                return itemId;
            }
        }
        catch(PreferenceNotFoundException ex)
        {
        }
        catch(ValueTypeViolationException ex)
        {
            throw new SystemException(ex);
        }
        
        return null;
    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/Customizations/Customization/Item. This XML element is OPTIONAL.
     * 
     * The customization item, which is a OrderItemReference, is not supported by GSI platform! null is returned.
     * 
     * @return data for OrderItem/Customization/Customizations/Customization/Item
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceCustomizationItem()
     */
    @Override
    public String getOrderServiceCustomizationItem()
    {
        return null;
    }

    /**
     * Returns if data is available to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/BasePrice. This XML element is OPTIONAL.
     * Checks if a base price is assigned to the customization.
     * BasePrice is the price charged when a customer requests any customization to a product. This is currently not contained in the Customization Engine Framework! Also on OMS side: The base price in the schema is not going to be used currently.
     * That's why always false is returned here.
     * 
     * @param baseProductLineItemBO  the parent PLI, the PLI of the base product
     * 
     * @return false - XML element should be omitted
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#hasOrderServiceBasePrice(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
     */
    @Override
    public boolean hasOrderServiceBasePrice(ProductLineItemBO baseProductLineItemBO)
    {
        return false;
    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/BasePrice/Amount. This XML element is OPTIONAL.
     * BasePrice is the price charged when a customer requests any customization to a product. This is currently not contained in the Customization Engine Framework! Also on OMS side: The base price in the schema is not going to be used currently.
     * That's why always null is returned here.
     * 
     * @param baseProductLineItemBO  the parent PLI, the PLI of the base product
     * 
     * @return data for OrderItem/Customization/BasePrice/Amount
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceBasePriceAmount(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
     * @see #hasOrderServiceBasePrice(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
     */
    @Override
    public BigDecimal getOrderServiceBasePriceAmount(ProductLineItemBO baseProductLineItemBO)
    {
        return null;
    }

//    /**
//     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/BasePrice/PromotionalDiscounts. This XML element is OPTIONAL.
//     * Each element in the returned collection is used to create one OrderItem/Customization/BasePrice/PromotionalDiscounts/Discount XML element.
//     * The BasePrice is the price charged when a customer requests any customization to a product. This is currently not contained in the Customization Engine Framework! Also on OMS side: The base price in the schema is not going to be used currently.
//     * That's why always null is returned here.
//     * 
//     * @param baseProductLineItemBO  the parent PLI, the PLI of the base product
//     * 
//     * @return data for OrderItem/Customization/BasePrice/PromotionalDiscounts, may return null or an empty collection
//     * 
//     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceBasePricePromotionalDiscounts(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
//     * @see #hasOrderServiceBasePrice(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
//     */
//    @Override
//    public Collection<GSITaxInformationBO> getOrderServiceBasePricePromotionalDiscounts(ProductLineItemBO baseProductLineItemBO)
//    {
//        return null;
//    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/BasePrice/TaxData/TaxClass. This XML element is OPTIONAL.
     * The BasePrice is the price charged when a customer requests any customization to a product. This is currently not contained in the Customization Engine Framework! Also on OMS side: The base price in the schema is not going to be used currently.
     * That's why always null is returned here.
     * 
     * @param baseProductLineItemBO  the parent PLI, the PLI of the base product
     * 
     * @return data for OrderItem/Customization/BasePrice/TaxData/TaxClass
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceBasePriceTaxDataTaxClass(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
     * @see #hasOrderServiceBasePrice(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
     */
    @Override
    public String getOrderServiceBasePriceTaxDataTaxClass(ProductLineItemBO baseProductLineItemBO)
    {
        // use tax class of base product
        return baseProductLineItemBO.getProduct().getTaxClassID();
    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/BasePrice/TaxData/Taxes. This XML element is OPTIONAL.
     * Each element in the returned collection is used to create one OrderItem/Customization/BasePrice/TaxData/Taxes/Tax XML element.
     * The BasePrice is the price charged when a customer requests any customization to a product. This is currently not contained in the Customization Engine Framework! Also on OMS side: The base price in the schema is not going to be used currently.
     * That's why always null is returned here.
     * 
     * @param baseProductLineItemBO  the parent PLI, the PLI of the base product
     * 
     * @return data for OrderItem/Customization/BasePrice/TaxData/Taxes, may return null or an empty collection
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceBasePriceTaxDataTaxes(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
     * @see #hasOrderServiceBasePrice(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
     */
    @Override
    public Collection<GSITaxInformationBO> getOrderServiceBasePriceTaxDataTaxes(ProductLineItemBO baseProductLineItemBO)
    {
        return null;
    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/BasePrice/UnitPrice. This XML element is OPTIONAL.
     * The BasePrice is the price charged when a customer requests any customization to a product. This is currently not contained in the Customization Engine Framework! Also on OMS side: The base price in the schema is not going to be used currently.
     * That's why always null is returned here.
     * 
     * @param baseProductLineItemBO  the parent PLI, the PLI of the base product
     * 
     * @return data for OrderItem/Customization/BasePrice/UnitPrice
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceBasePriceUnitPrice(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
     * @see #hasOrderServiceBasePrice(com.intershop.sellside.appbase.b2c.capi.order.ProductLineItemBO)
     */
    @Override
    public BigDecimal getOrderServiceBasePriceUnitPrice(ProductLineItemBO baseProductLineItemBO)
    {
        return null;
    }

    /**
     * Returns the data to be filled into order service XML element OrderCreateRequest/Order/OrderItems/OrderItem/Customization/DisplayUrl. This XML element is OPTIONAL.
     * 
     * This is the full URL to access a product detail page with all the customization selections.
     * 
     * @return data for OrderItem/Customization/DisplayUrl
     * 
     * @see com.gsi.webstore.platform.storefront.capi.basket.ProductConfigurationLineItemBOGSIExtension#getOrderServiceDisplayUrl()
     */
    @Override
    public String getOrderServiceDisplayUrl()
    {
        AbstractProductConfigurationBO productConfiguration =  delegate.getProductConfigurationOptionSelection().getConfiguration(); 
        ProductBO product = productConfiguration.getProduct(); 
        
        if (null != product)
        {
            Parameters params = new Parameters();
            params.addParameter("SKU", product.getSKU());
            params.addParameter("customizationID", productConfiguration.getName());
            Action action = new Action("ViewCart-UpdateVariation");
            URLComposition urlComposition = new URLComposition();
            return urlComposition.createSessionlessURL(action, params);
        }
        
        return null;
    }
}
